package swimv2.session;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.jboss.ejb3.annotation.RemoteBinding;
import org.jboss.util.NotImplementedException;

import com.arjuna.ats.internal.jdbc.drivers.modifiers.list;

import swimv2.entity.*;

/**
 * Session Bean implementation class WorkModuleBean
 */
@Stateless
@RemoteBinding( jndiBinding = "IWorkModuleRemote" )
public class WorkModuleBean implements IWorkModuleRemote {
	
	@PersistenceContext(unitName = "swimv2")
	protected EntityManager manager;

    /**
     * Default constructor. 
     */
    public WorkModuleBean() {
    }

	@Override
	public boolean sendPrivateRequest(Integer IdUser, String Subject,
			String Text, Integer IdUser_Receiver) {
		
		if(!Subject.isEmpty() && !Text.isEmpty())
		{
			Request m = new Request();
			m.setMessage(Text);
			m.setObject(Subject);
			
			User sender = manager.find(User.class, IdUser);
			User receiver = manager.find(User.class, IdUser_Receiver);
			if(sender!=null && receiver!=null)
			{
				//User Exist
				m.setPublic(false);
				m.setSender(sender);
				m.setReceiver(receiver);
				
				manager.persist(m);
				return true;
			}
		}
		return false;
	}

	@Override
	public boolean sendPrivateRequest(Integer IdUser, Message m,
			Integer IdUser_Receiver) {
		throw new NotImplementedException();
	}

	@Override
	public boolean sendPublicRequest(Integer IdUser, String Subject, String Text) {
		
		/*if(Subject.isEmpty())
		{
			throw new IllegalArgumentException();
		}*/
		
		if(!Subject.isEmpty() && !Text.isEmpty())
		{
			Request m = new Request();
			m.setMessage(Text);
			m.setObject(Subject);
			
			User sender = manager.find(User.class, IdUser);
			
			if(sender!=null)
			{
				//User Exist
				m.setPublic(true);
				m.setSender(sender);
				
				manager.persist(m);
				return true;
			}
		}
		return false;
	}

	@Override
	public boolean sendPublicRequest(Integer IdUser, Message m) {
		throw new NotImplementedException();
	}

	@Override
	public boolean respond(Integer IdUser, String Subject, String Text, Integer Id_Request,
			Integer Id_Response) {
		if(this.validConversation(Id_Request,Id_Response))
		{
			Integer lastMessageID = this.getLastMessage(Id_Response);
			
			Message m = manager.find(Message.class, lastMessageID);
			
			if(!Subject.isEmpty() && !Text.isEmpty())
			{
				Response nm = new Response();
				nm.setMessage(Text);
				nm.setObject(Subject);
				
				User sender = manager.find(User.class, IdUser);
				
				if(sender!=null)
				{
					//User Exist
					nm.setSender(sender);
					
					m.setNext(nm);
					
					manager.persist(nm);
					manager.persist(m);
					return true;
				}
			}
		}
		return false;
	}

	

	@Override
	public boolean giveFeedBack(Integer IdUser,Integer punteggio, String Commento,
			Integer Id_Request, Integer Id_Response) {
		if(this.validConversation(Id_Request,Id_Response))
		{
			Integer lastMessageID = this.getLastMessage(Id_Response);
			
			Message m = manager.find(Message.class, lastMessageID);
			
			if(punteggio>=0)
			{
				Response nm = new Response();
				nm.setMessage("L'utente ha deciso di votare il tuo supporto!"
						+Commento
						);
				nm.setObject("Voted");
				nm.setChosen(true);
				
				Request r = manager.find(Request.class, Id_Request);
				Feedback f = new Feedback();
				f.setPunteggio(punteggio);
				r.setFeedback(f);
				
				User sender = manager.find(User.class, IdUser);
				
				if(sender!=null)
				{
					//User Exist
					nm.setSender(sender);
					nm.setRejected(true);
					m.setNext(nm);
					
					manager.persist(nm);
					manager.persist(m);
					manager.persist(f);
					return true;
				}
			}
		}
		return false;
	}

	@Override
	public boolean respondAndReject(Integer idUser, String Subject,
			String Text, Integer Id_Request, Integer Id_Response) {
		
		Request rq = manager.find(Request.class, Id_Request);
		Response re = manager.find(Response.class, Id_Response);
		if(rq!=null && re!=null && this.validConversation(Id_Request,Id_Response))
		{
			Integer lastMessageID = this.getLastMessage(Id_Response);
			
			Message m = manager.find(Message.class, lastMessageID);
			
			User sender = manager.find(User.class, idUser);
			if(!Subject.isEmpty() && !Text.isEmpty() && sender!=null)
			{
				Response nresp = new Response();
				m.setNext(nresp);
				nresp.setMessage(Text);
				nresp.setObject(Subject);
				nresp.setSender(sender);
				
				manager.persist(m);
				manager.persist(nresp);
			}
		}
		else if (rq!=null && re==null)
		{
			User sender = manager.find(User.class, idUser);
			if(!Subject.isEmpty() && !Text.isEmpty() && sender!=null)
			{
				
				re = new Response();
				re.setMessage(Text);
				re.setObject(Subject);
				re.setSender(sender);
				re.setReceiver(rq.getSender());
				rq.setNext(re);
				
				manager.persist(re);
				manager.persist(rq);
			}
			
		}
		return false;
	}

	
	private Integer getLastMessage(Integer id_Response) {
		List<Message> listaMessaggi = new ArrayList<Message>();
		
		Response r = manager.find(Response.class, id_Response);
		
		Request rq = (Request)manager.createQuery("SELECT r " +
				"FROM Request r " +
				"WHERE r.next.id = :id")
				.setParameter("id", r.getId())
				.getSingleResult();
		
		
		listaMessaggi.add(rq);
		listaMessaggi.add(r);
		
		Message temp = r;
		while(temp.getNext()!=null)
		{
			listaMessaggi.add(temp);
			temp = temp.getNext();
		}
		
		
		return (temp!=null)?temp.getId():null;
	}

	private boolean validConversation(Integer id_Request, Integer id_Response) {
		Request r =(Request)manager.createQuery("SELECT r FROM Request r JOIN r.next as m WHERE r.id= :idr AND m.id = :idm")
					.setParameter("idr", id_Request)
					.setParameter("idm", id_Request)
					.getSingleResult();
		return (r != null);
	}

	@Override
	public List<Response> getConversations(Integer IdUser) {
		List<Response> r =(List<Response>)manager.createQuery(
				"SELECT rs " +
				"FROM Request rq JOIN rq.next rs " +
				"WHERE rs.sender.id = :id OR rs.receiver.id = :id")
				.setParameter("id", IdUser)
				.getResultList();
		return r;
	}

	@Override
	public List<Request> getPublicRequest(Integer IdUtente) {
		List<Request> r =(List<Request>)manager.createQuery(
				"SELECT r " +
				"FROM Request r " +
				"WHERE r.isPublic=true AND " +
				"r.sender.id != :id")
				.setParameter("id", IdUtente)
				.getResultList();
		return r;
	}

	@Override
	public List<Message> getMessageFromConversation(Integer IdConv) {
		
		List<Message> listaMessaggi = new ArrayList<Message>();
		
		Response r = manager.find(Response.class, IdConv);
		
		Request rq = (Request)manager.createQuery("SELECT r " +
				"FROM Request r " +
				"WHERE r.next.id = :id")
				.setParameter("id", r.getId())
				.getSingleResult();
		
		
		listaMessaggi.add(rq);
		listaMessaggi.add(r);
		
		Message temp = r.getNext();
		while(temp!=null)
		{
			listaMessaggi.add(temp);
			temp = temp.getNext();
		}
		
		
		return listaMessaggi;
	}

	@Override
	public Message getMessage(Integer id) {
		return manager.find(Message.class, id);
	}

	@Override
	public Request getRequest(Integer id) {
		
		return manager.find(Request.class, id);
	}
}
